package cn.dengta.webapp.trade.service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.function.Function;

import cn.dengta.webapp.base.service.BaseServiceImpl;
import cn.dengta.webapp.trade.dao.UserStatDao;
import cn.dengta.webapp.trade.dto.UserStatChangeDTO;
import cn.dengta.webapp.trade.entity.UserStat;
import cn.dengta.webapp.trade.model.TradeType;
import cn.dengta.webapp.user.model.Gender;
import lombok.extern.slf4j.Slf4j;
import me.codeplayer.util.EasyDate;
import org.springframework.stereotype.Service;

/**
 * 用户多维度汇总统计表 服务类
 *
 * @author Ready
 * @since 2022-09-19
 */
@Slf4j
@Service
public class UserStatService extends BaseServiceImpl<UserStat, UserStatDao, Long> {

	/***
	 * 更新牵线性别
	 */
	public int updatePullWireGender(Long userId, Integer gender){
		return baseDao.updatePullWireGender(userId, gender);
	}

	/**
	 * 初始化 单个用户的汇总统计数据行
	 */
	public int initForUser(Long userId) {
		return baseDao.initForUser(userId);
	}

	/**
	 * 初始化 用户性别
	 */
	public int initForGender(Long userId, Gender gender) {
		return baseDao.initForGender(userId, gender.value);
	}

	/**
	 * 初始化 推广员
	 */
	public int initForInvite(Long userId, Long inviteUserId) {
		return baseDao.initForInvite(userId, inviteUserId);
	}

	// 统一开启时间 "2023-01-12 15:30:00" 必须是上线成功后的一个时间
	static final long openTime = new EasyDate(2023, 1, 12, 15, 30).getTime();

	static boolean shouldNotSync(Date now) {
		return now.getTime() <= openTime;
	}

	/**
	 * 同步更新用户指标统计数据
	 */
	public void sync(UserStatChangeDTO dto) {
		if (shouldNotSync(dto.getNow())) {
			return;
		}
		final TradeType tradeType = dto.getTradeType();
		switch (tradeType) {
			case COIN_RECHARGE:
				baseDao.addRechargeSum(dto);
				break;
			case COIN_FOR_GREET: // 以下类型的 付费 和 收益 是分开执行的
				if (dto.getIncomeIntegral() == null) {
					baseDao.addGreetCost(dto);
				} else {
					baseDao.addMsgIncome(dto); // 搭讪算文字聊天收益
				}
				break;
			case COIN_FOR_MSG:
				baseDao.addMsgCost(dto);
				final BigDecimal integral = dto.getIncomeIntegral();
				log.info("文字消息积分={}, 用户id={}", integral, dto.getToUserId());
				if (integral != null && integral.compareTo(BigDecimal.ZERO) > 0) {
					baseDao.addMsgIncome(dto);
				}
				break;
			case COIN_FOR_VIDEO: // 以下类型的 付费、收益 是一并执行的
			case COIN_FOR_AUDIO:
			case COIN_FOR_GIFT: {
				Function<UserStatChangeDTO, Integer> pay, income;
				switch (tradeType) {
					case COIN_FOR_VIDEO:
						pay = baseDao::addVideoCost;
						income = baseDao::addVideoIncome;
						break;
					case COIN_FOR_AUDIO:
						pay = baseDao::addAudioCost;
						income = baseDao::addAudioIncome;
						break;
					case COIN_FOR_GIFT:
						pay = baseDao::addGiftCost;
						income = baseDao::addGiftIncome;
						break;
					default:
						throw new UnsupportedOperationException();
				}
				final Long payUserId = dto.getPayUserId(), incomeUserId = dto.getIncomeUserId();
				if (payUserId < incomeUserId) { // 避免出现并发死锁冲突
					pay.apply(dto);
					income.apply(dto);
				} else {
					income.apply(dto);
					pay.apply(dto);
				}
			}
			break;
			/*
			case COIN_FOR_AUDIO:
				addOtherIncome(dto);
				break;
			*/
		}
	}

	/**
	 * 累加 其它收益
	 */
	public int addOtherIncome(UserStatChangeDTO dto) {
		final BigDecimal integral = dto.getIncomeIntegral();
		if (integral != null && integral.compareTo(BigDecimal.ZERO) > 0) {
			return baseDao.addOtherIncome(dto);
		}
		return 0;
	}

	/**
	 * 累加 背包礼物收益
	 */
	public int addPackGiftIncome(UserStatChangeDTO dto) {
		final BigDecimal integral = dto.getIncomeIntegral();
		if (integral != null && integral.compareTo(BigDecimal.ZERO) > 0) {
			return baseDao.addGiftIncome(dto);
		}
		return 0;
	}

	/**
	 * 为 历史用户 初始化 指标数据
	 */
	public int initForOldUsers(Long maxUserId) {
		return baseDao.initForOldUsers(maxUserId);
	}

	/**
	 * 为 历史用户 累加历史 充值金额
	 */
	public int initForOldRecharges(Long minRechargeLogId, Long maxRechargeLogId) {
		return baseDao.initForOldRecharges(minRechargeLogId, maxRechargeLogId);
	}

	/**
	 * 为 历史用户 累加 搭讪次数
	 */
	public int initForOldGreets(Long minGreetLogId, Long maxGreetLogId) {
		return baseDao.initForOldGreets(minGreetLogId, maxGreetLogId);
	}

	/**
	 * 为 历史用户 累加 礼物消耗、视频消耗、语音消耗
	 */
	public int initForGiftAndVideoCosts(Long minUserCoinLogId, Long maxUserCoinLogId) {
		return baseDao.initForGiftAndVideoCosts(minUserCoinLogId, maxUserCoinLogId);
	}

	/**
	 * 为 历史用户 初始化 可用金币余额
	 */
	public int initForOldCoins(Long minUserId, Long maxUserId) {
		return baseDao.initForOldCoins(minUserId, maxUserId);
	}

	/**
	 * 为 历史用户 初始化 各种收益
	 */
	public int initForIncomes(Long minUserIntegralLogId, Long maxUserIntegralLogId) {
		return baseDao.initForIncomes(minUserIntegralLogId, maxUserIntegralLogId);
	}

	/**
	 * 为 历史用户 初始化 视频通话时间、次数
	 */
	public int initForVideoTimes(Long minMediaLogId, Long maxMediaLogId) {
		return baseDao.initVideoTimesForFromUser(minMediaLogId, maxMediaLogId)
				+ baseDao.initVideoTimesForToUser(minMediaLogId, maxMediaLogId);
	}

	/**
	 * 更新 所属推广员
	 */
	public int replaceTopInviteUserId(Long newTopInviteUserId, Long oldTopInviteUserId) {
		return baseDao.replaceTopInviteUserId(newTopInviteUserId, oldTopInviteUserId);
	}
}
